package com._5704.website.controller;


import com._5704.website.entity.Project;
import com._5704.website.entity.User;
import com._5704.website.exception.WebsiteException;
import com._5704.website.exception.WebsiteExceptionEnum;
import com._5704.website.form.ProjectForm;
import com._5704.website.service.ServiceImpl.ProjectServiceImpl;
import com._5704.website.service.ServiceImpl.UserServiceImpl;
import com._5704.website.util.JsonUtil;
import com._5704.website.util.JwtUtil;
import com._5704.website.vo.JsonVO;
import com._5704.website.vo.projectVO.ProjectAndMembersVO;
import com._5704.website.vo.userVO.UserVO;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Yiyoung
 * @since 2021-07-25
 */
@RestController
@RequestMapping("/project")
@Validated
@Log4j2
public class ProjectController {
    @Autowired
    private ProjectServiceImpl projectService;
    @Autowired
    private UserServiceImpl userService;


    @PostMapping("/create")
    @RequiresRoles("insider")
    @Transactional
    public JsonVO create(@Valid @RequestBody ProjectForm projectForm,
                         BindingResult bindingResult,
                         @RequestHeader("token") String token){
        // 获得用户id
        String userId = JwtUtil.getUserId(token);

        // 新建项目并获得项目id
        int id = projectService.createProject(projectForm, userId);

        // 创建成员
        projectService.setMember(userId, id);

        return JsonUtil.success();
    }

    /**
     * 展示一个项目
     * @param id 项目id
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/show")
    public JsonVO show(@RequestParam Integer id, @RequestHeader("token")String token){
        // 获得项目
        Project project = projectService.getProject(id);

        // 获得成员
        List<User> userList = projectService.getMembers(id);

        // 设置成员VO
        List<UserVO> userVOList = new ArrayList<>();
        userList.forEach(user -> userVOList.add(userService.getUserVO(user)));
        // 获得leaderVO
        UserVO leaderVO =  userService.getUserVO(userService.getUser(project.getLeadUserId()));
        // VO
        ProjectAndMembersVO projectAndMembersVO =  projectService.getProjectAndMembersVO(
                projectService.getProjectVO(project,leaderVO),
                userVOList);
        return JsonUtil.success(projectAndMembersVO);
    }

    /**
     * 获得多个活动
     * @param page 页数
     * @param num 数量
     * @param token token
     * @return
     */

    @RequiresRoles("insider")
    @GetMapping("/showMany")
    public JsonVO showMany(@Min(value = 0,message = "页数不能少于0") @RequestParam  int page,
                           @Min(value = 1,message = "数量不能少于1") @RequestParam  int num,
                           @RequestParam(required = false) boolean isGetMine,
                           @RequestParam(required = false) boolean isGetPart,
                           @RequestParam(required = false) String projectName,
                           @RequestHeader("token")String token){
        // 获得活动
        List<Project> projectList;
        // 是否获得自己创建的
        if (isGetMine){
            projectList  = projectService.getMyProject(JwtUtil.getUserId(token),page,num);
        }else if (isGetPart) {
            projectList  = projectService.getPartProject(JwtUtil.getUserId(token),page,num);
        }else if(projectName != null) {
            projectList  = projectService.getProjectByName(projectName,page,num);
        }else{
                projectList = projectService.getProjects(page,num);
        }

        // VO
        List<ProjectAndMembersVO> projectAndMembersVOList = new ArrayList<>();

        // 遍历设置每一个项目的VO
        projectList.forEach(project -> {
            // 获得成员
            List<User> userList = projectService.getMembers(project.getId());

            // 设置成员VO
            List<UserVO> userVOList = new ArrayList<>();
            userList.forEach(user -> userVOList.add(userService.getUserVO(user)));

            // 获得leaderVO
            UserVO leaderVO =  userService.getUserVO(userService.getUser(project.getLeadUserId()));

            // 单个VO
            projectAndMembersVOList.add(projectService.getProjectAndMembersVO(
                    projectService.getProjectVO(project,leaderVO),
                    userVOList));
        });


        return JsonUtil.success(projectAndMembersVOList);
    }

    /**
     * 参与项目
     * @param id 项目id
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/participate")
    public JsonVO participate(@RequestParam Integer id,  @RequestHeader("token") String token){
        String userId = JwtUtil.getUserId(token);

        // 获得项目来检查项目存在否
        projectService.getProject(id);

        // 检查人员是否满了
        if(projectService.isMemberFull(id)){
            throw new WebsiteException(WebsiteExceptionEnum.MEMBER_HAS_FULL);
        }
        // 检查是否团队成员
        if (projectService.isMember(userId, id)) {
            throw new WebsiteException(WebsiteExceptionEnum.USER_HAS_PARTICIPATED);
        }
        // 设置member
        projectService.setMember(userId, id);

        return JsonUtil.success();
    }

    /**
     * 退出项目
     * @param id 项目id
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/quite")
    public JsonVO quite(@RequestParam Integer id,  @RequestHeader("token") String token){
        String userId = JwtUtil.getUserId(token);

        // 获得项目来检查项目存在否
        projectService.getProject(id);

        // 检查人员是否为创建者
        if(projectService.isCreator(id,userId)){
            throw new WebsiteException(WebsiteExceptionEnum.MEMBER_IS_CREATOR);
        }
        // 检查是否团队成员
        if (!projectService.isMember(userId, id)) {
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_PARTICIPATED);
        }
        // 取消member
        projectService.cancelMember(userId,id);

        return JsonUtil.success();
    }

    /**
     * 踢出
     * @param id 项目id
     * @param userId 用户id
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/quiteUser")
    public JsonVO<String> quiteUser(@RequestParam Integer id, @RequestParam String userId,  @RequestHeader("token") String token){
        String leaderUserId = JwtUtil.getUserId(token);

        // 获得项目来检查项目存在否
        projectService.getProject(id);

        // 检查请求人员是否为创建者或管理员
        if(!projectService.isCreator(id,leaderUserId) && !userService.isAdmin(userService.getUser(leaderUserId))){
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_CREATOR_OR_ADMIN);
        }
        // 检查人员是否为创建者
        if(projectService.isCreator(id,userId)){
            throw new WebsiteException(WebsiteExceptionEnum.MEMBER_IS_CREATOR);
        }
        // 检查是否团队成员
        if (!projectService.isMember(userId, id)) {
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_PARTICIPATED);
        }

        // 取消member
        projectService.cancelMember(userId,id);

        return JsonUtil.success();

    }

    /**
     * 删除项目
     * @param id 项目id
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/delete")
    public JsonVO<String> delete(@RequestParam Integer id, @RequestHeader("token")String token){
        String userId = JwtUtil.getUserId(token);
        // 判断是否存在
        Project project = projectService.getProject(id);

        // 检查人员是否为创建者
        if(!projectService.isCreator(id,userId) && !userService.isAdmin(userService.getUser(userId))){
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_CREATOR_OR_ADMIN);
        }

        // 删除
        projectService.delete(project);

        return JsonUtil.success();
    }

    /**
     * 修改项目信息
     * @param projectForm 修改表单
     * @param token token
     * @return
     */
    @RequiresRoles("insider")
    @PostMapping("/modify")
    public JsonVO<String> modify(@Valid @RequestBody ProjectForm projectForm, @RequestHeader("token")String token){
        Integer id = projectForm.getId();
        String userId = JwtUtil.getUserId(token);
        if (id == null){
            throw new WebsiteException(WebsiteExceptionEnum.DATA_ERROR,"id不能为空");
        }

        // 得到活动
        Project project = projectService.getProject(id);

        // 检查人员是否为创建者
        if(!projectService.isCreator(id,userId) && !userService.isAdmin(userService.getUser(userId))){
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_CREATOR_OR_ADMIN);

        }
//        // 设置更新信息
//        if (projectForm.getFile() != null){
//            projectService.uploadPic((MultipartFile) projectForm.getFile(), id);
//
//        }
        projectService.setModifyData(project, projectForm);

        // 更新活动
        projectService.updateProject(project);

        return JsonUtil.success();
    }

    /**
     * 获得总数
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/getNum")
    public JsonVO<Object> getNum( @RequestParam(required = false) boolean isGetMine,
                                  @RequestParam(required = false) boolean isGetPart,
                                  @RequestParam(required = false) String isSearch,
                                  @RequestHeader("token")String token){
        int num;
        if (isGetMine){
           num =  projectService.getMineNum(JwtUtil.getUserId(token));
        }else if(isGetPart){
            num = projectService.getPartNum(JwtUtil.getUserId(token));
        }else if(isSearch != null){
            num = projectService.getNum(isSearch);
        }else{
            num = projectService.getNum();
        }

        Map<String,Integer> numMap = new HashMap<>();

        numMap.put("num",num);

        return JsonUtil.success(numMap);
    }

    /**
     * 获得总数
     * @return
     */
    @RequiresRoles("insider")
    @GetMapping("/search")
    public JsonVO<Object> search(@RequestParam String name,
                                 @Min(value = 0,message = "页数不能少于0") @RequestParam  int page,
                                 @Min(value = 1,message = "数量不能少于1") @RequestParam  int num,
                                 @RequestHeader("token")String token){
        List<Project> projectByName = projectService.getProjectByName(name, page, num);

        // 遍历设置每一个项目的VO
        List<ProjectAndMembersVO> projectAndMembersVOList = new ArrayList<>();
        projectByName.forEach(project -> {
            // 获得成员
            List<User> userList = projectService.getMembers(project.getId());

            // 设置成员VO
            List<UserVO> userVOList = new ArrayList<>();
            userList.forEach(user -> userVOList.add(userService.getUserVO(user)));

            // 获得leaderVO
            UserVO leaderVO =  userService.getUserVO(userService.getUser(project.getLeadUserId()));

            // 单个VO
            projectAndMembersVOList.add(projectService.getProjectAndMembersVO(
                    projectService.getProjectVO(project,leaderVO),
                    userVOList));
        });


        return JsonUtil.success(projectAndMembersVOList);
    }


    @RequiresRoles("user")
    @PostMapping("/uploadPic")
    public JsonVO<String> uploadAvatar(@RequestParam MultipartFile file, @RequestParam("id")Integer id){




        projectService.uploadPic(file, id);

        return JsonUtil.success();
    }
}
